﻿using System.Runtime.InteropServices;
using System.Text;

namespace NexC_Sharp.Services
{
    public static class Nex
    {
        private const string DllName = "libnrc_host.dll";

        // 连接控制器
        [DllImport(DllName)]
        public static extern int connect_robot(string ip, string port, string robotName);

        // 断开控制器
        [DllImport(DllName)]
        public static extern int disconnect_robot(string robotName);

        // 获得控制器连接状态
        [DllImport(DllName)]
        public static extern int get_connection_status(string robotName);

        // 伺服清错
        [DllImport(DllName)]
        public static extern int clear_error(string robotName);

        // 设置伺服状态
        [DllImport(DllName)]
        public static extern int set_servo_state(int state, string robotName);

        // 获取伺服状态
        [DllImport(DllName)]
        public static extern int get_servo_state(string robotName);

        // 机器人上电
        [DllImport(DllName)]
        public static extern int set_servo_poweron(string robotName);


        // 机器人下电
        [DllImport(DllName)]
        public static extern int set_servo_poweroff(string robotName);

        // 获取机器人当前位置
        [DllImport(DllName)]
        public static extern int get_current_position([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos, int coord, string robotName);

        // 获取机器人外部轴当前位置
        [DllImport(DllName)]
        public static extern int get_current_extra_position([MarshalAs(UnmanagedType.LPArray, SizeConst = 5)] double[] pos, string robotName);

        // 获取机器人运行状态
        [DllImport(DllName)]
        public static extern int get_robot_running_state(string robotName);


        // 设置当前模式的速度
        [DllImport(DllName)]
        public static extern int set_speed(int speed, string robotName);

        // 获得当前模式的速度
        [DllImport(DllName)]
        public static extern int get_speed(string robotName);

        // 设置机器人当前坐标系
        [DllImport(DllName)]
        public static extern int set_current_coord(int coord, string robotName);

        // 获取机器人当前坐标系
        [DllImport(DllName)]
        public static extern int get_current_coord(string robotName);

        // 设置机器人当前模式
        [DllImport(DllName)]
        public static extern int set_current_mode(int mode, string robotName);

        // 获取机器人当前模式
        [DllImport(DllName)]
        public static extern int get_current_mode(string robotName);

        // 设置数字输出
        [DllImport(DllName)]
        public static extern int set_digital_output(int port, int value, string robotName);

        // 一次获取所有数字输出
        [DllImport(DllName)]
        public static extern int get_digital_output(int[] output, string robotName);

        // 一次获取所有数字输入
        [DllImport(DllName)]
        public static extern int get_digital_input(int[] input, string robotName);

        // 设置模拟输出
        [DllImport(DllName)]
        public static extern int set_analog_output(int port, double value, string robotName);

        // 查询模拟输出
        [DllImport(DllName)]
        public static extern int get_analog_output([MarshalAs(UnmanagedType.LPArray, SizeConst = 64)] double[] aout, string robotName);

        // 设置工具手编号
        [DllImport(DllName)]
        public static extern int set_tool_hand_number(int toolNum, string robotName);


        // 获取当前使用的工具手编号
        [DllImport(DllName)]
        public static extern int get_tool_hand_number(out int toolNum, string robotName);

        // 设置工具手参数
        [DllImport(DllName)]
        public static extern int set_tool_hand_param(int toolNum, [MarshalAs(UnmanagedType.LPArray, SizeConst = 6)] double[] toolParam, string robotName);

        // 设置用户坐标编号
        [DllImport(DllName)]
        public static extern int set_user_coord_number(int userNum, string robotName);

        // 获取当前使用的用户坐标编号
        [DllImport(DllName)]
        public static extern int get_user_coord_number(out int userNum, string robotName);

        // 获取当前使用的用户坐标的参数
        [DllImport(DllName)]
        public static extern int get_user_coord_para(int userNum, [MarshalAs(UnmanagedType.LPArray, SizeConst = 6)] double[] pos, string robotName);

        // 设置全局位置
        [DllImport(DllName)]
        public static extern int set_global_position(string posName, [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] posInfo, string robotName);

        // 查询全局位置
        [DllImport(DllName)]
        public static extern int get_global_position(string posName, [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos, string robotName);

        // 设置全局变量
        [DllImport(DllName)]
        public static extern int set_global_variant(string varName, double varValue, string robotName);

        // 查询全局变量
        [DllImport(DllName)]
        public static extern int get_global_variant(string varName, out double value, string robotName);

        // 根据点位名修改当前作业文件局部点位
        [DllImport(DllName)]
        public static extern int set_local_position(string posName, [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] posInfo, string robotName);

        // 设置零点位置
        [DllImport(DllName)]
        public static extern int set_axis_zero_position(int axis, string robotName);

        // 设置零点偏移
        [DllImport(DllName)]
        public static extern int set_zero_pos_shift(int axis, double shift, string robotName);

        // 获取单圈值
        [DllImport(DllName)]
        public static extern int get_single_cycle([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] single_cycle, string robotName);


        // 查询4点标定
        [DllImport(DllName)]
        public static extern int get_four_point([MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] double[] result, string robotName);

        // 进行4点标记
        [DllImport(DllName)]
        public static extern int set_four_point_mark(int point, int status, [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] double[] result, string robotName);

        // 4点标定计算
        [DllImport(DllName)]
        public static extern int four_point_calculation(double L1, double L2, [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] double[] result, string robotName);

        // 将4点标定计算的结果写入机器人DH参数
        [DllImport(DllName)]
        public static extern int set_result_for_DH(string robotName);

        // 查询电机扭矩
        [DllImport(DllName)]
        public static extern int get_motor_torque([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] torq, [MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] maxTorq, [MarshalAs(UnmanagedType.LPArray, SizeConst = 5)] double[] torqSync, [MarshalAs(UnmanagedType.LPArray, SizeConst = 5)] double[] maxTorqSync, string robotName);

        // 开始点动
        [DllImport(DllName)]
        public static extern int robot_start_jogging(int axis, bool dir, string robotName);

        // 停止点动
        [DllImport(DllName)]
        public static extern int robot_stop_jogging(int axis, string robotName);

        // 关节运动
        [DllImport(DllName)]
        public static extern int robot_movej([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos, int vel, int coord, int acc, int dec, string robotName);

        // 直线运动
        [DllImport(DllName)]
        public static extern int robot_movel([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos, int vel, int coord, int acc, int dec, string robotName);


        // 圆弧运动
        [DllImport(DllName)]
        public static extern int robot_movec([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos1, [MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos2, [MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos3, int vel, int coord, int acc, int dec, string robotName);

        // 样条曲线运动
        [DllImport(DllName)]
        public static extern int robot_moves(int size, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] double[][] pos, int vel, int coord, int acc, int dec, string robotName);

        // 外部轴关节运动
        [DllImport(DllName)]
        public static extern int robot_extra_movej([MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos, int vel, int coord, int acc, int dec, string robotName);

        // 外部轴直线运动
        [DllImport(DllName)]
        public static extern int robot_extra_movel([MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos, int vel, int coord, int acc, int dec, string robotName);

        // 外部轴圆弧运动
        [DllImport(DllName)]
        public static extern int robot_extra_movec([MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos1, [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos2, [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)] double[] pos3, int vel, int coord, int acc, int dec, string robotName);

        // 根据文件夹上传一整个文件夹的作业文件
        [DllImport(DllName)]
        public static extern int job_upload_by_directory(string directoryPath, string robotName);

        // 根据文件名上传一个作业文件
        [DllImport(DllName)]
        public static extern int job_upload_by_file(string filePath, string robotName);

        // 下载所有作业文件到指定文件夹
        [DllImport(DllName)]
        public static extern int job_download_by_directory(string directoryPath, bool isCover, string robotName);

        // 删除指定的作业文件
        [DllImport(DllName)]
        public static extern int job_delete(string jobName, string robotName);

        // 打开指定的作业文件
        [DllImport(DllName)]
        public static extern int job_open(string jobName, string robotName);

        // 运行指定的作业文件
        [DllImport(DllName)]
        public static extern int job_run(string jobName, string robotName);

        // 单步运行指定的作业文件的某一行
        [DllImport(DllName)]
        public static extern int job_step(string jobName, int line, string robotName);

        // 暂停指定的作业文件
        [DllImport(DllName)]
        public static extern int job_pause(string robotName);

        // 继续运行作业文件
        [DllImport(DllName)]
        public static extern int job_continue(string robotName);

        // 停止指定的作业文件
        [DllImport(DllName)]
        public static extern int job_stop(string robotName);

        [DllImport(DllName)]
        public static extern int job_get_current_file(StringBuilder jobname, string robotName);

        // 设置作业文件运行次数
        [DllImport(DllName)]
        public static extern int job_run_times(int index, string robotName);

        // 继续运行作业文件
        [DllImport(DllName)]
        public static extern int job_break_point_run(string robotName);

        [DllImport(DllName)]
        public static extern int weld_get_config(int index, out double voltage, out double current, string robotName);

        [DllImport(DllName)]
        public static extern int queue_motion_set_status(bool status, string robotName);

        [DllImport(DllName)]
        public static extern int queue_motion_get_status(out bool status, string robotName);

        [DllImport(DllName)]
        public static extern int queue_motion_send_to_controller(int size, string robotName);

        [DllImport(DllName)]
        public static extern int queue_motion_push_back_moveJ([MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos, int coord, double velocity, double acc, double dec, int pl, int toolNum, int userNum, string robotName);

        [DllImport(DllName)]
        public static extern int set_receive_error_or_warnning_message_callback(ErrorCallback callback, string robotName);

        public delegate void ErrorCallback(int type, IntPtr errorMesg, int code);

        private static ErrorCallback? errorCallbackDelegate;

        public static void SetErrorCallback(ErrorCallback callback, string robotName)
        {
            errorCallbackDelegate = callback;
            Nex.set_receive_error_or_warnning_message_callback(errorCallbackDelegate, robotName);
        }

        [DllImport(DllName)]
        public static extern int conveyor_belt_tracking_set_basic_parameter(
    int encoderVal, int time, int encoderDirection, double encoderResolution,
    double maxEncoderVal, double minEncoderVal, int posRecordMode, double speed,
    int userCoord, int conveyorID, int height, int trackOnRunModeWithTargetOverrun,
    int compensationEncoderVal, string robotName);

        [DllImport(DllName)]
        public static extern int conveyor_belt_tracking_set_identification_parameter(
            int conveyorID, int detectSrcType, int capturePos, int visionID,
            int visionIoFilterType, int visionLatchEncoderValueType, int communication,
            int sensorTrg, int type, string robotName);

        [DllImport(DllName)]
        public static extern int conveyor_belt_tracking_set_sensor_calibration(
            int conveyorID, [MarshalAs(UnmanagedType.LPArray, SizeConst = 6)] double[] sensorPos, string robotName);

        [DllImport(DllName)]
        public static extern int conveyor_belt_tracking_set_tracking_range(
            int conveyorID, double receLatestPos, double trackRangeXMax, double trackRangeYMax,
            double trackRangeYMin, double trackRangeZMax, double trackRangeZMin,
            double trackStartXPoint, string robotName);

        [DllImport(DllName)]
        public static extern int conveyor_belt_tracking_set_tracking_wait_point(
            int conveyorID, bool isWait, double delayDetectTime,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 7)] double[] pos, string robotName);

    }
}
